package com.chuan.base.util;

import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import org.apache.commons.lang3.RandomStringUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.common.collect.Maps;
import com.shuodao.common.model.MsgSendResult;
import com.shuodao.common.model.Result;
import com.shuodao.common.util.RequestUtil;
import com.shuodao.common.util.SendMsgUtil;


public class VerifyCodeUtil {

	private static final int PERIOD_MINS = 30; // 次数限制周期时长分钟数
	private static final int PERIOD_GET_COUNT = 3; // 周期内限制的次数
	private static final int INTERVAL_SECONDS = 60; // 两次发送之间至少的间隔
	private static final int CODE_VERIFY_COUNT = 3; // 一条验证码可验证次数
	private static final int CODE_VALID_TIME = 10; // 一次验证码有效时长分钟数
	private static final String REGIST_VERIFY_CODE = "REGIST_VERIFY_CODE"; // 验证码
	private static final String REGIST_PHONE_SESSION_KEY = "REGIST_PHONE_KEY"; // 手机号
	private static final String REGIST_VERIFY_COUNT_KEY = "REGIST_VERIFY_COUNT_KEY"; // 验证过几次
	private static final String REGIST_CODE_GET_COUNT_KEY = "REGIST_CODE_GET_COUNT_KEY"; // 共获取多少次
	private static final String LAST_SEND_TIME = "LAST_SEND_TIME"; // 上次发送时间毫秒数
	private static final String THIS_PERIOD_START_TIME = "THIS_PERIOD_START_TIME"; // 本周期开始毫秒数
	
	private static final Logger logger = LoggerFactory.getLogger(VerifyCodeUtil.class);
	
	public static String sendSmgCode(String phone,String signName){
		logger.info("签名"+ phone + "  " + signName);
		HttpSession session = RequestUtil.getSession();
		HttpServletRequest request = RequestUtil.getRequest();
		Map<String, Object> infoMap = Maps.newHashMap();
		long nowMillis = System.currentTimeMillis();
		Long startMillis = (Long) session.getAttribute(THIS_PERIOD_START_TIME);
		Long lastMillis = (Long) session.getAttribute(LAST_SEND_TIME);
		Integer getCount = (Integer) session.getAttribute(REGIST_CODE_GET_COUNT_KEY);
		if (getCount == null)
			getCount = 0;
		boolean periodStart = (getCount % PERIOD_GET_COUNT) == 0;
		if (lastMillis != null && nowMillis < (startMillis + INTERVAL_SECONDS * 1000L)) {
			return Result.fail("发送间隔时间过短").json();
		}
		if (startMillis != null && nowMillis < (startMillis + PERIOD_MINS * 60000L) && periodStart) {
			return Result.fail("请求过于频繁").json();
		}
		session.setAttribute(REGIST_PHONE_SESSION_KEY, phone);
		String vCode = RandomStringUtils.random(4, false, true);
		String clientIp = RequestUtil.getRealIp(request);
		MsgSendResult msgSendRes;
		if(signName!=null) {
			msgSendRes = SendMsgUtil.sendMsg(phone, signName, clientIp, "您的验证码为{}", vCode);
		}else {
			msgSendRes = SendMsgUtil.sendMsg(phone, 1, "您的验证码为"+vCode);
		}
		if (!msgSendRes.success()) {
			return Result.fail(msgSendRes.getMsg()).json();
		}
		logger.info(phone+"发送短信验证码成功。");
		session.setAttribute(REGIST_CODE_GET_COUNT_KEY, getCount + 1);
		if (periodStart) {
			session.setAttribute(THIS_PERIOD_START_TIME, nowMillis);
		}
		session.setAttribute(LAST_SEND_TIME, nowMillis);
		session.setAttribute(REGIST_VERIFY_CODE, vCode);
		logger.info("短信验证码为"+vCode);
		session.setAttribute(REGIST_VERIFY_COUNT_KEY, 0);
		session.setAttribute(REGIST_PHONE_SESSION_KEY, phone);
		infoMap.put("left_seconds", INTERVAL_SECONDS);
		return Result.success(infoMap).json();
	}	
	
	public static String verifySmeCode(String phoneNum, String verifyCode) {
		HttpSession session = RequestUtil.getSession();
		// 开始验证手机验证码
		String smsCodePhone = (String) session.getAttribute(REGIST_PHONE_SESSION_KEY);
		if (StringUtils.isBlank(smsCodePhone) || !smsCodePhone.equals(phoneNum)) {
			return Result.fail("手机没有被检查").json();
		}
		if (StringUtils.isBlank(verifyCode)) {
			return Result.fail("验证码为空").json();
		}
		Integer verifyCount = (Integer) session.getAttribute(REGIST_VERIFY_COUNT_KEY);
		if (verifyCount == null)
			verifyCount = 0;
		if (verifyCount >= CODE_VERIFY_COUNT) {
			return Result.fail("验证码失效").json();
		}
		String sCode = (String) session.getAttribute(REGIST_VERIFY_CODE);
		if (StringUtils.isBlank(sCode)) {
			return Result.fail("请重新验证").json();
		}
		Long lastSendTime = (Long) session.getAttribute(LAST_SEND_TIME);
		long nowMillis = System.currentTimeMillis();
		if (lastSendTime == null || nowMillis > lastSendTime + (CODE_VALID_TIME * 60000L)) {
			return Result.fail("验证码失效").json();
		}
		if (!sCode.equals(verifyCode)) {
			session.setAttribute(REGIST_VERIFY_COUNT_KEY, ++verifyCount);
			return Result.fail("验证码不匹配").json();
		}
		return Result.success().json();
	}
}
